#ifndef _ITEMS_H_
#define _ITEMS_H_


#include "Common.h"
#include "String.h"
#include "SharedPtr.h"
#include "Resource.h"
#include "Vector3.h"
#include "ItemModels.h"
#include "Effects.h"
#include "XMLData.h"

class Item;
class ItemPtr;
class MissionPtr;
class CreatureAIScript;

	

typedef 	std::map<uint8,int32>		ItemAttributeMap;


//物品公共属性
#define  ITEM_ATTRIBUTES_NUM 	16       //值等于 Item::ItemAttributeNum
typedef struct item_common_property
{

	float		finalHP;	//物品最大生命
	float		finalProtect;	//物品的最大保护

	//物品最终影响的属性 
	ItemAttributeMap	attributes;
	//来至数据库，
	ItemAttributeMap	attributeOrg;
	//加成 来至与套装，镶嵌 物品加成，效果
	ItemAttributeMap	attributeExt;

	//是否打开武器附加效果
	bool	enable_effect1;
	bool	enable_effect2;
	bool	enable_effect3;
	
	Vector3		position;
	uint8		dir;

	uint32		data1;
	uint32		data2;
	uint32		data3;
	uint32		data4;

	float		fdata1;
	float		fdata2;
	
	void	*	ext;		//数据扩展
	
	ResourceProxy		uplink; //父级对象连接
	void initialize(void)
	{
		
		finalHP = 0;
		finalProtect = 0;

		attributes.clear();
		attributeOrg.clear();
		attributeExt.clear();

		enable_effect1 = false;
		enable_effect2 = false;
		enable_effect3 = false;
	
		data1 = 0;
		data2 = 0;
		data3 = 0;
		data4 = 0;

		fdata1 = 0;
		fdata2 = 0;
		
		ext = NULL;
				
		position = Vector3::ZERO;
		dir = 0;
		uplink.setNull();
	}

	float getAttribute(const uint8 & id)
	{
		if(id <1 || id >= ITEM_ATTRIBUTES_NUM)
			return 0;
		else
			return attributes[id];
	}

	item_common_property()
	{
		initialize();
	}

}item_common_property_t;

class Item :public Resource
{
public:
	enum ItemStatus
	{
		ItemStatusNone			= 0,	//无效状态
		ItemStatusNormal		= 1,	//一般状态
		ItemStatusUse			= 2,	//使用，装备，作用状态
		ItemStatusFreeze		= 3,	//物品冻结状态
		ItemStatusDeath			= 4,	//损坏，死亡状态
		ItemStatusDeleted		= 255	//物品数据删除
	};

	enum ItemAttribute
	{
		ItemAttributeNone		= 0,	//无效属性
		ItemAttributeHPMax		= 1,	//最大生命属性
		ItemAttributeProtectMax		= 2,	//最大保护属性
		ItemAttributeHP			= 3,	//当前生命
		ItemAttributePower		= 4,	//蓄力当前值
		ItemAttributePowerMax		= 5,	//蓄力最大值	
		
		ItemAttributeNum		= 6
	};


	typedef 	std::map<uint8,int32>		ItemAttributeMap;


	Item(ResourceManager* creator, const String& name, ResourceHandle handle,
            const String& group, bool isManual = false, ManualResourceLoader* loader = 0);
	~Item(void);

protected:
       	void prepareImpl(void);
        /** Destroys data cached by prepareImpl.
         */
        void unprepareImpl(void);
        /// @copydoc Resource::loadImpl
        bool loadImpl(void);
        /// @copydoc Resource::postLoadImpl
        void postLoadImpl(void);

	 void preUnloadImpl(void);
        /// @copydoc Resource::unloadImpl
        void unloadImpl(void);
        /// @copydoc Resource::calculateSize
        size_t calculateSize(void) const;

	bool loadChildrenFromDB(void);
	
	ItemAttributeMap	m_itemAttributes;

private:
	std::list<ResourceProxy>	m_items;	// 如果为容器物品，包含的物品序列号
	std::list<ResourceProxy>	m_effects;	// 物品作用的效果
	std::list<ResourceProxy>	m_missions;	// 物品作用的效果
	
	uint64		m_guid;
	uint32		m_serial;
	uint32		m_group_id;
	String 	m_name; 	// '物品名称',
	bool		m_db_loaded;

	void    initialize(void);
public:

	const uint32  & getSerial() 	{	return m_serial;	}
	const uint32  & getGroup_id()	{	return m_group_id;	}
	const uint64  & getGuid()	{	return m_guid;		}
	void setGuid(const uint64 & set)	{	m_guid = set;	}

	//用户数据
        XMLDataSet      user_data;

	bool hasChildren(void)  {       return false;    }

	//添加释放容器物品包含的物品
	bool	addItem(const uint32 & serial);
	bool  	addItem(ResourceProxy & item);
	bool	removeItem(const uint32 & serial);
	bool	removeItem(ResourceProxy & item);
	bool	deleteItem(const uint32 & serial);
	bool	deleteItem(ResourceProxy & item);
	bool	destroyItem(const uint32 & serial);
	bool	destroyItem(ResourceProxy & item);
	void	removeAllItems(void);
	void	destroyAllItems(void);
	void	deleteAllItems(void);
	
	void	removeByParent(void);
	
	//添加效果到
	bool	addEffect(const uint32 & serial);
	bool	addEffect(ResourceProxy & effect);
	bool	removeEffect(const uint32 & serial);
	bool	removeEffect(ResourceProxy & effect);
	bool	deleteEffect(const uint32 & serial);
	bool	deleteEffect(ResourceProxy & effect);
	bool    destroyEffect(const uint32 & serial);
	bool	destroyEffect(ResourceProxy & effect);
	void	removeAllEffects(void);
	void	destroyAllEffects(void);
	void	deleteAllEffects(void);

	//任务操作
	bool	addMission(const uint32 & serial);
	bool	addMission(ResourceProxy & mission);
	bool	removeMission(const uint32 & serial);
	bool	removeMission(ResourceProxy & mission);
	bool	deleteMission(const uint32 & serial);
	bool	deleteMission(ResourceProxy & mission);
	bool    destroyMission(const uint32 & serial);
	bool 	destroyMission(ResourceProxy & mission);
	void	removeAllMissions(void);
	void	destroyAllMissions(void);
	void	deleteAllMissions(void);

	const String & getItemName(void);
	
	//得到包含物品的列表复制
	std::list<ItemPtr> * getItemsList(std::list<ItemPtr> * list);

	//得到包括特效的列表复制
	std::list<EffectPtr> * getEffectsList(std::list<EffectPtr> * list);

	//得到任务列表
	std::list<MissionPtr> * getMissionsList(std::list<MissionPtr> * list);
	

	//得到指定索引的属性 如果失败返回false
	bool getAttribute(const ItemAttribute & index, int32 * value = 0);
	//设置指定索引的属性 如果失败返回false
	bool setAttribute(const ItemAttribute & index, const int32 & value);
	//根据指定索引创建属性或者设置属性值
	bool createAttribute(const ItemAttribute & index, const int32 & value);
	//根据指定索引创建修改属性值
	bool modifyAttribute(const Item::ItemAttribute & index, const int32 & value);

	//得到物品的属性Map
	const ItemAttributeMap & getAttributes(void)	{	return m_itemAttributes;	}

	//得到属性定义数据库字符串
	String getAttributeString(void);
	//save attributes
	bool	SaveAttributes(void);
	void	LoadAttributes(void);

	//save item to database	
	bool	SaveDB(void);
	bool	LoadDB(void);	
	bool    FetchDB(Field * fields);


	size_t  loadItemsFromDB(void);
        size_t  loadEffectsFromDB(void);
	size_t  loadMissionsFromDB(void);

	ItemStatus	getItemStatus(void);
	void	setItemStatus(const ItemStatus & status);

	//冻结和死亡状态
	bool	isDeath(void);

	//物品的模式属性
	ItemModelPtr	model;

	//物品公共属性
	item_common_property_t	common;

	void Delete(void);
	void Destroy(void);
};

    /** Specialisation of SharedPtr to allow SharedPtr to be assigned to ItemPtr 
    @note Has to be a subclass since we need operator=.
    We could templatise this instead of repeating per Resource subclass, 
    except to do so requires a form VC6 does not support i.e.
    ResourceSubclassPtr<T> : public SharedPtr<T>
    */
    class SERVER_DECL  ItemPtr : public SharedPtr<Item>
    {
    public:
        ItemPtr() : SharedPtr<Item>() {}
        explicit ItemPtr(Item* rep) : SharedPtr<Item>(rep) {}
        ItemPtr(const ItemPtr& r) : SharedPtr<Item>(r) {}
        ItemPtr(const ResourcePtr& r);
        /// Operator used to convert a ResourcePtr to a MeshPtr
        ItemPtr& operator=(const ResourcePtr& r);
    protected:
        /// Override destroy since we need to delete Mesh after fully defined
        void destroy(void);
    };
	

#endif
